/*
 * SwingIconSet.java  0.4.0 / Oct 26, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing;

import com.cute4j.swing.graphics.Image;

/**
 * Icon Set.
 *
 * @cute4j.native
 *    generate="header"
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
final class SwingIconSet {

// Private Fields. -------------------------------------------------------------

  private final Component component;
  private Icon icon;
  private Icon pressedIcon;
  private Icon selectedIcon;
  private Icon disabledIcon;
  private Icon disabledSelectedIcon;
  private Icon rolloverIcon;
  private Icon rolloverSelectedIcon;

// Package-Private Fields. -----------------------------------------------------

  long _iconEnginePointer; // set by native code

// Package-Private Constructors. 0----------------------------------------------

  SwingIconSet(Component component) {
    this.component = component;
  }

// Package-Private Methods. ----------------------------------------------------

  Icon getIcon() {
    return icon;
  }

  Icon getPressedIcon() {
    return pressedIcon;
  }

  Icon getSelectedIcon() {
    return selectedIcon;
  }

  Icon getDisabledIcon() {
    return disabledIcon;
  }

  Icon getDisabledSelectedIcon() {
    return disabledSelectedIcon;
  }

  Icon getRolloverIcon() {
    return rolloverIcon;
  }

  Icon getRolloverSelectedIcon() {
    return rolloverSelectedIcon;
  }

  boolean setIcon(Icon icon, String property) {
    Icon oldIcon = this.icon;
    if (icon == null) {
      if (oldIcon != null) {
        this.icon = null;
        checkIconEnginePointer();
        _setIcon(_iconEnginePointer, 0);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        this.icon = icon;
        checkIconEnginePointer();
        _setIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setPressedIcon(Icon icon, String property) {
    Icon oldIcon = pressedIcon;
    if (icon == null) {
      if (oldIcon != null) {
        pressedIcon = null;
        checkIconEnginePointer();
        _removePressedIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        pressedIcon = icon;
        checkIconEnginePointer();
        _setPressedIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setSelectedIcon(Icon icon, String property) {
    Icon oldIcon = selectedIcon;
    if (icon == null) {
      if (oldIcon != null) {
        selectedIcon = null;
        checkIconEnginePointer();
        _removeSelectedIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        selectedIcon = icon;
        checkIconEnginePointer();
        _setSelectedIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setDisabledIcon(Icon icon, String property) {
    Icon oldIcon = disabledIcon;
    if (icon == null) {
      if (oldIcon != null) {
        disabledIcon = null;
        checkIconEnginePointer();
        _removeDisabledIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        disabledIcon = icon;
        checkIconEnginePointer();
        _setDisabledIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setDisabledSelectedIcon(Icon icon, String property) {
    Icon oldIcon = disabledSelectedIcon;
    if (icon == null) {
      if (oldIcon != null) {
        disabledSelectedIcon = null;
        checkIconEnginePointer();
        _removeDisabledSelectedIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        disabledSelectedIcon = icon;
        checkIconEnginePointer();
        _setDisabledSelectedIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setRolloverIcon(Icon icon, String property) {
    Icon oldIcon = rolloverIcon;
    if (icon == null) {
      if (oldIcon != null) {
        rolloverIcon = null;
        checkIconEnginePointer();
        _removeRolloverIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        rolloverIcon = icon;
        checkIconEnginePointer();
        _setRolloverIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean setRolloverSelectedIcon(Icon icon, String property) {
    Icon oldIcon = rolloverSelectedIcon;
    if (icon == null) {
      if (oldIcon != null) {
        rolloverSelectedIcon = null;
        checkIconEnginePointer();
        _removeRolloverSelectedIcon(_iconEnginePointer);
        releaseIcon(oldIcon);
        notifyComponent(property, oldIcon, null);
        return true;
      }
    } else {
      if (!icon.equals(oldIcon)) {
        rolloverSelectedIcon = icon;
        checkIconEnginePointer();
        _setRolloverSelectedIcon(_iconEnginePointer, acquireIcon(icon));
        notifyComponent(property, oldIcon, icon);
        return true;
      }
    }
    return false;
  }

  boolean isEmpty() {
    return ((icon == null) && (pressedIcon == null) && (selectedIcon == null) &&
            (disabledIcon == null) && (disabledSelectedIcon == null) &&
            (rolloverIcon == null) && (rolloverSelectedIcon == null));
  }

// Package-Private Methods (used by the native code). --------------------------

  boolean _isDisableIconSet() {
    return (disabledIcon != null);
  }

  int _getIconWidth(int type) {
    Icon icon = getIcon(type);
    if (icon != null) {
      return icon.getIconWidth();
    }
    return 0;
  }

  int _getIconHeight(int type) {
    Icon icon = getIcon(type);
    if (icon != null) {
      return icon.getIconHeight();
    }
    return 0;
  }

  void _paintIcon(long paintDevicePointer, int type) {
    Icon icon = getIcon(type);
    if (icon != null) {
      SwingGraphics graphics = new SwingGraphics(paintDevicePointer);
      icon.paintIcon(component, graphics, 0, 0);
      graphics.dispose();
    }
  }

// Private Methods. ------------------------------------------------------------

  private void checkIconEnginePointer() {
    if (_iconEnginePointer == 0) {
      throw new OutOfMemoryError("Null _iconEnginePointer pointer");
    }
  }

  private void notifyComponent(String property, Icon oldIcon, Icon newIcon) {
    if (property != null) {
      component.firePropertyChange(property, oldIcon, newIcon);
      component.invalidate();
      component.repaint();
    }
  }

  private Icon getIcon(int type) {
    switch (type) { // NOPMD
      case 1:
        if (pressedIcon != null) {
          return pressedIcon;
        }
        break;
      case 2:
        if (selectedIcon != null) {
          return selectedIcon;
        }
        break;
      case 3:
        if (disabledIcon != null) {
          return disabledIcon;
        }
        break;
      case 4:
        if (disabledSelectedIcon != null) {
          return disabledSelectedIcon;
        }
        break;
      case 5:
        if (rolloverIcon != null) {
          return rolloverIcon;
        }
        break;
      case 6:
        if (rolloverSelectedIcon != null) {
          return rolloverSelectedIcon;
        }
        break;
    }
    return icon;
  }

  private long acquireIcon(Icon icon) {
    if (icon.getClass() == ImageIcon.class) {
      Image image = ((ImageIcon)icon).getImage();
      if (image.getClass() == SwingImage.class) { // (image != null) always
        return ((SwingImage)image).acquireImagePointer();
      }
    }
    return 0;
  }

  private void releaseIcon(Icon icon) {
    if (icon.getClass() == ImageIcon.class) {
      Image image = ((ImageIcon)icon).getImage();
      if (image.getClass() == SwingImage.class) { // (image != null) always
        ((SwingImage)image).releaseImagePointer();
      }
    }
  }

// Package-Private Native Methods. ---------------------------------------------

  native void _setIcon(long iconEnginePointer, long imagePointer);

  native void _setSelectedIcon(long iconEnginePointer, long imagePointer);

  native void _removeSelectedIcon(long iconEnginePointer);

  native void _setPressedIcon(long iconEnginePointer, long imagePointer);

  native void _removePressedIcon(long iconEnginePointer);

  native void _setDisabledIcon(long iconEnginePointer, long imagePointer);

  native void _removeDisabledIcon(long iconEnginePointer);

  native void _setDisabledSelectedIcon(long iconEnginePointer,
                                       long imagePointer);

  native void _removeDisabledSelectedIcon(long iconEnginePointer);

  native void _setRolloverIcon(long iconEnginePointer, long imagePointer);

  native void _removeRolloverIcon(long iconEnginePointer);

  native void _setRolloverSelectedIcon(long iconEnginePointer,
                                       long imagePointer);

  native void _removeRolloverSelectedIcon(long iconEnginePointer);

}
